<?php
/**
* phpCan - http://idc.anavallasuiza.com/
*
* phpCan is released under the GNU Affero GPL version 3
*
* More information at license.txt
*/

namespace PHPCan\Cache;

defined('ANS') or die();

class Files implements iCache
{
    private $Debug;
    private $loaded;
    private $settings;

    /**
     * public function __construct ([string $autoglobal], [array $settings])
     *
     * return none
     */
    public function __construct ($autoglobal = '', $settings = array())
    {
        global $Debug;

        $this->Debug = $Debug;
        $this->settings = $settings;

        if ($autoglobal) {
            global $Config;

            $Config->config['autoglobal'][] = $autoglobal;
        }
    }

    /**
    * public function connect (string $type)
    *
    * Connect to memcached server
    *
    * return boolean
    */
    public function connect ($type)
    {
        $this->folder = filePath('phpcan/cache|'.alphaNumeric($type));

        if ($this->loaded = is_writable($this->folder)) {
            return $this;
        }

        $base = dirname($this->folder);

        $this->loaded = (!is_dir($base) || !is_writable($base) || is_dir($this->folder) || !mkdir($this->folder, 0700)) ? false : true;

        return $this->loaded ? $this : false;
    }

    /**
     * private function _fileName (string $file, [int/string $time], [string $flags])
     *
     * returns a filename to save in cache
     *
     * return false/string
     */
    private function _fileName ($file, $time = 0, $flags = '')
    {
        if (strpos($file, '://') !== false) {
            $file = parse_url($file, PHP_URL_PATH);
        }

        $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
        $ext = strstr($ext, 'php') ? 'txt' : $ext;

        return $this->folder.'/'.md5($file.serialize($flags)).($ext ? ('.'.$ext) : '');
    }

    /**
    * public function exists ($name)
    *
    * Check variable exists in memory
    *
    * return boolean
    */
    public function exists ($name)
    {
        if (!$this->loaded) {
            return false;
        }

        $name = $this->_fileName($name);

        return (is_file($name) && (filemtime($name) > time())) ? true : false;
    }

    /**
    * public function set ($name, $value, [$expire integer])
    *
    * Set a variable into memory
    *
    * return mixed
    */
    public function set ($name, $value, $expire = 3600)
    {
        if (!$this->loaded) {
            return $value;
        }

        $name = $this->_filename($name);

        if (!is_file($name) || is_writable($name)) {
            $contents = serialize($value);
            $contents = $this->settings['compress'] ? gzdeflate($contents) : $contents;

            file_put_contents($name, $contents);

            touch($name, time() + $expire);
        }

        return $value;
    }

    /**
    * public function get ($name)
    *
    * Get a variable from memory
    *
    * return mixed
    */
    public function get ($name)
    {
        if (!$this->loaded) {
            return null;
        }

        $name = $this->_fileName($name);

        if (!is_file($name) || (filemtime($name) < time())) {
            return null;
        }

        $contents = file_get_contents($name);

        return unserialize($this->settings['compress'] ? gzinflate($contents) : $contents);
    }

    /**
    * public function delete ($name)
    *
    * Delete a variable from memory
    *
    * return mixed
    */
    public function delete ($name)
    {
        if ($this->loaded) {
            return null;
        }

        $name = $this->_fileName($name);

        return is_file($name) ? unlink($name) : null;
    }

    /**
    * public function clear (void)
    *
    * Clear APC cache
    *
    * return mixed
    */
    public function clear ()
    {
        return true;
    }

    /**
    * public function expire ($key)
    *
    * Return the time to expire a key
    *
    * return mixed
    */
    public function expire ($key)
    {
        if (!$this->loaded) {
            return null;
        }

        return false;
    }
}
